package conf

import (
	"gitee.com/whilew/cream/pkg/util/xcast"
	"strings"
)

type Settings []*Setting
type Setting struct {
	Key    string
	Value  interface{}
	Childs Settings
}

func (ss *Settings) SetConfigByMap(data map[string]interface{}) {
	var recursionSetConfig func(key string, d map[string]interface{})
	recursionSetConfig = func(key string, d map[string]interface{}) {
		for k, v := range d {
			if vv, ok := v.(map[string]interface{}); ok {
				recursionSetConfig(key+k+".", vv)
			} else {
				ss.SetConfig(splitConfigKey(key+k), v)
			}
		}
	}
	recursionSetConfig("", data)
}
func (ss *Settings) SetConfig(key []string, value interface{}) {
	var find_key = func(s *Setting) {
		if len(key) > 1 {
			if s.Childs == nil {
				s.Childs = Settings{}
			}
			s.Childs.SetConfig(key[1:], value)
		} else {
			s.Value = value
		}
	}
	for i, t := range *ss {
		if t.Key == key[0] {
			find_key((*ss)[i])
			return
		}
	}
	s := &Setting{
		Key: key[0],
	}
	find_key(s)
	*ss = append(*ss, s)
}
func (s *Settings) find(keys []string) interface{} {
	for _, t := range *s {
		if t.Key == keys[0] {
			if len(keys) > 1 {
				return t.Childs.find(keys[1:])
			} else {
				return t.Value
			}
		}
	}
	return nil
}
func (s *Settings) Get(key string) interface{} {
	keys := strings.Split(strings.ToLower(key), ".")
	return s.find(keys)
}
func (s *Settings) GetString(key string) string {
	return xcast.ToString(s.Get(key))
}
func (s *Settings) GetStringd(key, dv string) string {
	v := s.GetString(key)
	if v == "" {
		return dv
	}
	return v
}
func (s *Settings) GetBool(key string) bool {
	return xcast.ToBool(s.Get(key))
}
func (s *Settings) GetBoold(key string, dv bool) bool {
	if v := s.Get(key); v == nil {
		return dv
	} else {
		return xcast.ToBool(dv)
	}
}
func (s *Settings) GetInt(key string) int {
	return xcast.ToInt(s.Get(key))
}
func (s *Settings) GetIntd(key string, dv int) int {
	if v := s.Get(key); v == nil {
		return dv
	} else {
		return xcast.ToInt(v)
	}
}
func (s *Settings) GetInt64(key string) int64 {
	return xcast.ToInt64(s.Get(key))
}
func (s *Settings) GetInt64d(key string, dv int64) int64 {
	if v := s.Get(key); v == nil {
		return dv
	} else {
		return xcast.ToInt64(v)
	}
}
func (s *Settings) GetFloat64(key string) float64 {
	return xcast.ToFloat64(s.Get(key))
}
func (s *Settings) GetFloat64d(key string, dv float64) float64 {
	if v := s.Get(key); v == nil {
		return dv
	} else {
		return xcast.ToFloat64(v)
	}
}
func (s *Settings) GetStringSlice(key string) []string {
	return xcast.ToStringSlice(key)
}
func (s *Settings) GetChildd(key string) *Settings {
	if v := s.Get(key); v == nil {
		return &Settings{}
	} else {
		if v, ok := v.(*Settings); ok {
			return v
		} else {
			return &Settings{}
		}
	}
}
